package com.well.rpc.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.well.rpc.WellRpcException;
import com.well.rpc.config.ClientDataConfig;
import com.well.rpc.job.JobHandler;
import com.well.rpc.model.CodeInfo;
import com.well.rpc.model.EventType;
import com.well.rpc.model.JobHandlerModel;
import com.well.rpc.model.TransData;
import com.well.rpc.register.RegisterClient;
import com.well.rpc.utils.ThreadPoolUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.net.SocketAddress;
import java.util.List;


/**
 * <p>
 * 客户端连接服务端时初始化
 * </p>
 *
 * @author weedo
 * @since 2022/8/6
 */
@Slf4j
public class ClientHandler {

    private static ChannelHandlerContext channelContext;

    /* heard data to server */
    private static String HEARD_DATA = "hello, server!";

    /**
     * 设置channel Context
     * @param channelHandlerContext
     */
    public static void setChannelContext(ChannelHandlerContext channelHandlerContext) {
        if (channelHandlerContext == null || channelHandlerContext.isRemoved()) return;
        channelContext = channelHandlerContext;
    }

    /**
     * 健康检查
     */
    public static boolean isHealth() {
        return channelContext != null && !channelContext.isRemoved();
    }

    /**
     * 获取真实channel
     * @return
     */
    private static Channel channel() {
        if (!isHealth()) {
            throw new WellRpcException(CodeInfo.CHANNEL_NOT_HEALTH.getCode(), CodeInfo.CHANNEL_NOT_HEALTH.getMsg());
        }
        return channelContext.channel();
    }

    /**
     * 组装消息
     * @return
     */
    private static TransData getTransData(EventType type, Object msg) {
        TransData transData = new TransData();
        transData.setType(type);
        transData.setJsonData(JSONObject.toJSONString(msg));
        return transData;
    }

    /**
     * 连接服务器
     * @param serverIp
     * @param port
     */
    public static void connectServer(String serverIp, Integer port) {
        RegisterClient.connect(serverIp, port);
    }

    /**
     * 通过线程池异步执行任务注册
     */
    public static void registerWellJobHandlers() {
        List<JobHandlerModel> allJobHandlerModel = JobHandler.getAllJobHandlerModel();
        if (allJobHandlerModel.isEmpty()) {
            return;
        }
        ThreadPoolUtils.execute(() -> {
            while (!ClientDataConfig.getClientRegisterStatus()) {
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.warn(JSON.toJSONString(allJobHandlerModel));
            writeToServer( EventType.REGISTER_JOB, allJobHandlerModel);
        });
    }

    /**
     * 通道初始化
     */
    public static void initClient() {
        writeToServer(ClientDataConfig.getRegisterTransData());
        registerWellJobHandlers();
    }

    /**
     * 发送消息到服务中心
     */
    public static void writeToServer(EventType type, Object msg) {
        writeToServer(getTransData(type, msg));
    }

    /**
     * 发送消息到服务中心
     */
    public static void writeToServer(TransData transData) {
        channel().writeAndFlush(transData);
    }

    /**
     * 心跳检查
     */
    public static void heartBeat() {
        writeToServer(EventType.HEARTBEAT, HEARD_DATA);
    }
}
